﻿using SiMay.Sockets.Tcp.Session;
using System;

namespace SiMay.Sockets.Tcp.Pooling
{

    /// <summary>
    /// Session堆栈池
    /// </summary>
    public class SessionPool : ObjectPool<TcpSocketSaeaSession>
    {
        private Func<TcpSocketSaeaSession> _createSaea;
        private Action<TcpSocketSaeaSession> _cleanSaea;

        /// <summary>
        /// 初始化池
        /// </summary>
        /// <param name="createSaea">创建异步对象方法</param>
        /// <param name="cleanSaea">清除异步对象方法</param>
        /// <param name="initialCount">池中创建多少个异步操作对象</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public SessionPool Initialize(Func<TcpSocketSaeaSession> createSaea, Action<TcpSocketSaeaSession> cleanSaea, int initialCount = 0)
        {
            if (createSaea == null)
                throw new ArgumentNullException("createSaea");
            if (cleanSaea == null)
                throw new ArgumentNullException("cleanSaea");

            _createSaea = createSaea;
            _cleanSaea = cleanSaea;

            if (initialCount < 0)
                throw new ArgumentOutOfRangeException("initialCount", initialCount, "Initial count must not be less than zero.");

            //循环创建Session对象插入到堆栈中
            for (int i = 0; i < initialCount; i++)
            {
                Add(Create());
            }

            return this;
        }

        /// <summary>
        /// 创建Session对应的异步对象
        /// </summary>
        /// <returns></returns>
        protected override TcpSocketSaeaSession Create()
        {
            return _createSaea();
        }

        /// <summary>
        /// 重置异步对象,将异步对象返回池
        /// </summary>
        /// <param name="saea"></param>
        public void Return(TcpSocketSaeaSession saea)
        {
            _cleanSaea(saea);
            Add(saea);
        }
    }
}
